package com.link.server.core.character;

import com.link.database.entity.DBCharacter;

public class Character {
    private long id;//角色唯一标识符

    private long regionId; // 区域ID

    private long accountId;//关联角色所属的账户

    private String name; // 角色名称
    //资产信息
    private long gold; // 金币数量
    private long silver; // 银币数量
    private long copper; // 铜币数量
    private long lowGradeSpiritStone; // 下品灵石
    private long mediumGradeSpiritStone; // 中品灵石
    private long highGradeSpiritStone; // 上品灵石
    private long supremeGradeSpiritStone; // 极品灵石
    //装备穿戴信息
    private long weapon; // 武器
    private long secondaryWeapon; // 副武器

    private long head; // 头部装备
    private long shoulder; // 肩部装备
    private long hat; // 帽子
    private long coat; // 上衣
    private long pants; // 下装
    private long belt; // 腰带
    private long shoes; // 鞋子
    private long cloak; // 披风
    private long gloves; // 手套
    private long ring; // 戒指
    private long earring; // 耳环
    private long faceAccessory; // 脸饰
    private long necklace; // 项链
    // 灵宠信息
    private long petId; // 灵宠ID



    // 基础属性
    private long hp;
    private long hpMax;
    private long mp;
    private long mpMax;

    private long level; // 角色等级
    private long experience; // 角色经验值
    private long bone; // 筋骨
    private long fightingSpirit; // 斗志
    private long precision; // 精准
    private long physique; // 体魄
    private long movement; // 身法
    private long critical;// 会心
    private long criticalChance; // 会心率
    private long criticalDamage; // 会心伤害
    private long criticalDamageReduction; // 会心伤害减免
    private long dodgeRate; // 闪避率

    private long hitRate; // 命中率
    private long lifeStealRate; // 吸血率
    private long lifeStealResistance; // 吸血抵抗率

    private long moveSpeed; // 角色移动速度
    private long attackSpeed; // 角色攻击速度
    private long attack;// 攻击力
    private long defense; // 防御力
    private long hpBonus; // 生命加成




    private long attackBonus; // 攻击力加成

    private long defenseBonus; // 防御力加成
    private long damageReduction; // 伤害减免固定值
    private long damageReductionPercent; // 伤害减免百分比
    private long damageBonus; // 伤害加成
    private long damageBonusPercent; // 伤害加成百分比

    //灵根资质
    private long goldRoots; // 金灵根资质
    private long woodRoots; // 木灵根资质
    private long waterRoots; // 水灵根资质
    private long fireRoots; // 火灵根资质
    private long earthRoots; // 土灵根资质
    private long lightRoots; // 光灵根资质
    private long darkRoots; //暗灵根资质
    private long poisonRoots; // 毒灵根资质
    private long iceRoots; // 冰灵根资质
    private long thunderRoots; // 雷灵根资质


    //状态数据
    private long mapId;//所在地图
    private long x;//坐标X
    private long y;//坐标Y;


    public Character(DBCharacter dbCharacter) {

    }

    /**
     * 增加经验值
     *
     * @param value 增加的经验值
     */
    public void addExperience(long value) {
        this.experience += value;
        checkLevelUp();
    }

    /**
     * 检查是否升级
     */
    private void checkLevelUp() {
        long requiredExp = calculateRequiredExp(level);
        while (experience >= requiredExp) {
            experience -= requiredExp;
            level++;
            requiredExp = calculateRequiredExp(level);
            onLevelUp();
        }
    }

    /**
     * 计算升级所需经验值
     *
     * @param currentLevel 当前等级
     * @return 升级所需经验值
     */
    // 非线性经验公式：基础值 * (等级^曲线系数) + 等级 * 固定增量
// 曲线系数控制升级难度增长速度，固定增量保证基础增长
    private long calculateRequiredExp(long currentLevel) {
        final long BASE_EXP = 1000;
        final double EXP_CURVE = 1.5;
        final long LEVEL_INCREMENT = 500;

        return (long) (BASE_EXP * Math.pow(currentLevel, EXP_CURVE)) + currentLevel * LEVEL_INCREMENT;
    }

    /**
     * 升级时的属性提升
     */
    private void onLevelUp() {
        // 基础属性提升
        hpMax += 100;
        mpMax += 80;
        attack += 10;

        defense += 5;


        // 恢复满血满蓝
        hp = hpMax;
        mp = mpMax;


    }

    public long getHp() {
        return hp;
    }

    public void setHp(long hp) {
        this.hp = Math.min(hp, hpMax);

    }

    public long getHpMax() {
        return hpMax;
    }

    public void setHpMax(long hpMax) {
        this.hpMax = hpMax;
        this.hp = Math.min(this.hp, hpMax);
    }

    public void addHp(long value) {
        setHp(this.hp + value);
    }

    public void reduceHp(long value) {
        setHp(Math.max(0, this.hp - value));
    }

    public boolean isFullHp() {
        return hp >= hpMax;
    }

    public boolean isDead() {
        return hp == 0;
    }

    public long getMp() {
        return mp;
    }

    public void setMp(long mp) {
        this.mp = Math.min(mp, mpMax);
    }

    public long getMpMax() {
        return mpMax;
    }

    public void setMpMax(long mpMax) {
        this.mpMax = mpMax;
        this.mp = Math.min(this.mp, mpMax);
    }

    public void addMp(long value) {
        setMp(this.mp + value);
    }

    public void reduceMp(long value) {
        setMp(Math.max(0, this.mp - value));
    }

    public boolean isFullMp() {
        return mp >= mpMax;
    }


}
